<?php

require_once SITE_ROOT_PATH."/_lib/classes/model/BoookingDetails.php";
require_once SITE_ROOT_PATH."/_lib/classes/model/BookingRoons.php";
require_once SITE_ROOT_PATH."/_lib/classes/model/BookingGuests.php";
require_once SITE_ROOT_PATH."/_lib/classes/model/BookingPayment.php";

class bookings {

    private $booking_id, $params, $booking_result;

    public function getBooking_id() {
        return $this->booking_id;
    }

    public function setBooking_id($booking_id) {
        $this->booking_id = $booking_id;
    }

    public function getParams() {
        return $this->params;
    }

    public function setParams($params) {
        $this->params = $params;
    }

    public function getBooking_result() {
        return $this->booking_result;
    }

    public function setBooking_result($booking_result) {
        $this->booking_result = $booking_result;
    }

        
    // Remove all sessions - convert them to non globals
    function begin_booking($params, $forceInsert = false) {
        if (isset($_SESSION["booking_id"]) && ! $forceInsert) {
            $this->booking_id = $_SESSION["booking_id"];
            $this->booking_timestamp = $_SESSION["booking_timestamp"];
            $this->booking_auth_result = $_SESSION["booking_auth_result"];            
        } 
        if (!$this->booking_id || $forceInsert) {
            $p["booking_date"] = time();
            $p["user_ip"] = $_SERVER["REMOTE_ADDR"];
            $p["supplier_code"] = $params["supplier_code"];
            $p["currency"] = in($params["total_currency"]);
            $p["amount"] = in($params["total"]);
            $p['surcharge'] = $params['surcharge'];
            $p['nett_rate'] = $params['nett_rate']; 
            $p['sale_price'] = $params['sale_price']; 
            $p['total_price']= $params['total_price'];             
            $sql = "INSERT INTO bookings SET ".make_set_clause($p);  
            $result = mysql_query($sql) or die (mysql_error());
            // Set the booking id
            $this->booking_id = mysql_insert_id();    
            $this->booking_timestamp = date("YmdHis");
            $this->params = $params;
            // mark booking as started
            $_SESSION["booking_id"] = $this->booking_id;
            $_SESSION["booking_timestamp"] = $this->booking_timestamp;
            
        }else{
            $this->params = $params;
        }
    } 

    // authenticates credit card, prepares payment
    // which will be settled or voided later
    // based on success of travel agent request
    
    function auth_payment_realex(){
        $timestamp = date("YmdHis");
        $order_id = "LH-".pad_with_zeroes($this->booking_id, 7);
        $amount = number_format($this->params["total"], 2, "", "");
        $currency = $this->params["total_currency"];
        $ccn = $this->params["cc_number"];
        $string = $timestamp.".".REALEX_MERCHANTID.".".$order_id.".".$amount.".".$currency.".".$ccn;
        $sha1 = sha1($string);
        $sha1 = sha1($sha1.".".REALEX_SECRET);
        $xml = file_get_contents("realex_auth_request.xml");
        $data = array(
            "%timestamp%"   => $timestamp,
            "%merchantid%"  => REALEX_MERCHANTID,
            "%account%"     => REALEX_ACCOUNT,
            "%orderid%"     => $order_id,
            "%currency%"    => $currency,
            "%amount%"      => $amount,
            "%ccn%"         => $ccn,
            "%expdate%"     => $this->params["card_expiry_month"].$this->params["card_expiry_year"],
            "%ccname%"      => $this->params["cc_holder_name"],
            "%cctype%"      => $this->params["cc_type"],
            "%ccissueno%"   => "",
            "%cvn%"         => $this->params["cc_security_code"],
            "%comment%"     => $this->params["special_requirements"],
            "%ip%"          => $_SERVER["REMOTE_ADDR"],
            "%zipcode%"     => $this->params["cc_zipcode"],
            "%country%"     => $this->params["cc_country"],
            "%sha1hash%"    => $sha1
        );
        // do not log CC details
        $data_log = array(
            "%timestamp%"   => $timestamp,
            "%merchantid%"  => REALEX_MERCHANTID,
            "%account%"     => REALEX_ACCOUNT,
            "%orderid%"     => $order_id,
            "%currency%"    => $currency,
            "%amount%"      => $amount,
            "%ccn%"         => substr($ccn,-4),
            "%expdate%"     => $this->params["card_expiry_month"].$this->params["card_expiry_year"],
            "%ccname%"      => $this->params["cc_holder_name"],
            "%cctype%"      => $this->params["cc_type"],
            "%ccissueno%"   => "",
            "%cvn%"         => $this->params["cc_security_code"],
            "%comment%"     => $this->params["special_requirements"],
            "%ip%"          => $_SERVER["REMOTE_ADDR"],
            "%zipcode%"     => $this->params["cc_zipcode"],
            "%country%"     => $this->params["cc_country"],
            "%sha1hash%"    => $sha1
        );
        $xml_real = strtr($xml, $data);
        $xml_log = strtr($xml, $data_log);
        $reply = $this->execute_realex_request($xml_real);
        $xo = simplexml_load_string($reply);
        $p["result_credit_card"] = intval($xo->result);
        $p["result_credit_card_message"] = in((string)$xo->message);
        $p["pasref"] = in((string)$xo->pasref);
        $p["authcode"] = in((string)$xo->authcode);
        $p["batchid"] = in((string)$xo->batchid);
        $p["order_id"] = in((string)$xo->orderid);
        $p["status"] = 0;
        $this->booking_auth_result = $p;
        $query = "UPDATE bookings SET ".make_set_clause($p)." WHERE booking_id='$this->booking_id'";
        $ret = mysql_query($query) or die (mysql_error());
        // Remove the sesion variable from the class
        $_SESSION["booking_result_message"] = $p["result_message"];
        $_SESSION["booking_auth_result"] = $this->booking_auth_result;      

        return $p;
    }

    // Build a settle request
    function settle_payment_realex() {
        $timestamp = date("YmdHis");
        $order_id = "LH-".pad_with_zeroes($this->booking_id, 7);
        $amount = number_format($this->params["total_cost"], 2, "", "");
        $currency = $this->params["total_cost_currency"];
        $ccn = $this->params["cc_number"];
        $string = $timestamp.".".REALEX_MERCHANTID.".".$order_id."...";
        $sha1 = sha1($string);
        $sha1 = sha1($sha1.".".REALEX_SECRET);
        $xml = file_get_contents("realex_settle_request.xml");
        $data = array(
            "%timestamp%"   => $timestamp,
            "%merchantid%"  => REALEX_MERCHANTID,
            "%account%"     => REALEX_ACCOUNT,
            "%orderid%"     => $order_id,
            "%pasref%"      => $this->booking_auth_result["pasref"],
            "%authcode%"    => $this->booking_auth_result["authcode"],
            "%sha1hash%"    => $sha1
        );
        $xml = strtr($xml, $data);
        //$this->log_realex_transaction($xml, $order_id, "settle-".$timestamp);
        $reply = $this->execute_realex_request($xml);
        //$this->log_realex_transaction($reply, $order_id, "settle-".$timestamp."-reply");
        $xo = simplexml_load_string($reply);
        $p["settle_void_result"] = intval($xo->result);
        $p["settle_void_result_message"] = in((string)$xo->message);
        $p["batchid"] = in((string)$xo->batchid);
        $p["order_id"] = in((string)$xo->orderid);        
        $p["status"] = 1;
        $query = "UPDATE bookings SET ".make_set_clause($p)." WHERE booking_id='$this->booking_id'";
        $ret = mysql_query($query) or die (mysql_error());
        // Remove session variables from class
        $_SESSION["booking_result_message"] = $p["settle_void_result_message"];
        return $p;
    }

    // Build a void request
    function void_payment_realex($supplierMsg) {
        $timestamp = date("YmdHis");
        $order_id = "LH-".pad_with_zeroes($this->booking_id, 7);
        $amount = number_format($this->params["total_cost"], 2, "", "");
        $currency = $this->params["total_cost_currency"];
        $ccn = $this->params["cc_number"];
        $string = $timestamp.".".REALEX_MERCHANTID.".".$order_id."...";
        $sha1 = sha1($string);
        $sha1 = sha1($sha1.".".REALEX_SECRET);
        $xml = file_get_contents("realex_void_request.xml");
        $data = array(
            "%timestamp%"=>$timestamp,
            "%merchantid%"=>REALEX_MERCHANTID,
            "%account%"=>REALEX_ACCOUNT,
            "%orderid%"=>$order_id,
            "%pasref%"=>$this->booking_auth_result["pasref"],
            "%authcode%"=>$this->booking_auth_result["authcode"],
            "%sha1hash%"=>$sha1  
        );
        $xml = strtr($xml, $data);
        //$this->log_realex_transaction($xml, $order_id, "void-".$timestamp);
        //sent the xml to realex.
        $reply = $this->execute_realex_request($xml);
        //$this->log_realex_transaction($reply, $order_id, "void-".$timestamp."-reply");
        $xo = simplexml_load_string($reply);
        $p["settle_void_result"] = intval($xo->result);
        $p["settle_void_result_message"] = in((string)$xo->message);
        $p["batchid"] = in((string)$xo->batchid);
        $p["order_id"] = in((string)$xo->orderid);
        $p["status"] = -1;
        $p['supplier_message'] = $supplierMsg;
        $query = "UPDATE bookings SET ".make_set_clause($p)." WHERE booking_id='$this->booking_id'";
        error_log('[void_payment_realex] - Realizado o update: '.$query,0);        
        $ret = mysql_query($query) or die (mysql_error());
        // Remove session variables from classes
        $_SESSION["booking_result_message"] = $p["settle_void_result_message"];
        // @TODO check return var - do we need array?
        return $p["settle_void_result"]; 
    }

    // Function // option to log payment details to an XML file
    function log_realex_transaction($xml, $order_id, $timestamp) {
        $microseconds = (string) microtime(true);
        file_put_contents("logs/{$order_id}-{$timestamp}-{$microseconds}.xml", $xml);
    }

    // FUNCITON // Send a request to Realex
    function execute_realex_request($xml) {
        error_log('Enviando o xml para o realex' ,0);        
        $cache_key = "realex_".md5($xml);
        // do not send same request more than once
        if (!isset($_SESSION[$cache_key])) {
            // Send the request array to Realex Payments 
            $ch = curl_init();    
            curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
            curl_setopt($ch, CURLOPT_POST, 1); 
            curl_setopt($ch, CURLOPT_USERAGENT, "payandshop.com php version 0.9"); 
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            $response = curl_exec ($ch);     
            curl_close ($ch); 
            $_SESSION[$cache_key] = $response;
        } else {
            $response = $_SESSION[$cache_key];
        }
        return $response;
    }

    // Function // Insert a record of the booking to the database 
    function complete_booking($params) {
        //$params = calc_rate($params);
        $sql = "UPDATE bookings SET supplier_booking_ref = '".in($params["booking_ref"])."' 
                WHERE booking_id='".$this->booking_id."'";
        $result = mysql_query($sql) or die (mysql_error());
        return $result;  
    }

    // FUNCTION // validate the data on the booking form
    function validate_booking_form($form_data) {
        $my_array = array();
        $no_email_errors = true;
        if (!$form_data['lead_first_name']) {
            array_push($my_array, 'Please enter your name.');
        }
        if (!$form_data['lead_last_name']) {
            array_push($my_array, 'Please enter your last name.');
        }
        if (!validate_email($form_data['lead_epost1'])) {
            array_push($my_array, 'Please enter a valid email address.');
            $no_email_errors = false;
        }
        if (!$form_data['lead_epost2']) {
            array_push($my_array, 'Please re-enter your email address.');
            $no_email_errors = false;
        }
        if (($form_data['lead_epost1']!==$form_data['lead_epost2'])&&$no_email_errors) {
            array_push($my_array, 'The email addresses entered do not match.');
        }
        return $my_array;
    }

    // FUNCTION // validate the data on the booking form
    function validate_payment_form($form_data) {
        $my_array = array();
      
        if (!$form_data['cc_holder_name']) {
            array_push($my_array, 'Please enter the name of the credit card holder.');
        }
        if (!$form_data['cc_type']) {
            array_push($my_array, 'Please select the type of credit card.');
        }
        if (!$form_data['cc_number']) {
            array_push($my_array, 'Please enter the credit card number.');
        }
        if (!$form_data['cc_security_code']) {
            array_push($my_array, 'Please enter the last 3 digits of the card\'s security code (CVV).');
        }
        if (!$form_data['cc_address1']) {
            array_push($my_array, 'Please enter the card holders address.');
        }
        if (!$form_data['cc_city']) {
            array_push($my_array, 'Please enter the city.');
        }
        if (empty($my_array)){
           // $this->set_params($form_data);
            $result = $this->auth_payment_realex();
            if ($result["result_credit_card"] !=0) {
                array_push($my_array, 'Credit Card information incorrect');
           }
        }
        
        return $my_array;

    }
    
    
    function set_properties($params){
        $this->booking_id = $_SESSION["booking_id"];
        $this->booking_timestamp = $_SESSION["booking_timestamp"];
        $this->booking_auth_result = $_SESSION["booking_auth_result"];  
        $this->params = $params;                       
    }
    
    function map_booking_details_params($params){
        
        return array("booking_id" => $this->booking_id,
                     "check_in_date" => $params['check_in_date'],
                     "check_out_date" => $params['check_out_date'],
                     "num_night" => $params['num_night'],
                     "customer_tittle" => $params['title_room_1_adults_1'],
                     "customer_first_name" => $params['lead_first_name_room_1_adults_1'],
                     "customer_last_name" => $params['lead_last_name_room_1_adults_1'],
                     "customer_email" =>$params['lead_epost1'] ,
                     "customer_phone" => $params['lead_telephone'],
                     "num_room" => $params['num_room'],
                     "supplier_hotel_id" => $params['hotel_id'] );
    }
    
    function map_booking_rooms_params($params, $booking_detail_id){
        $params['booking_detail_id'] = $booking_detail_id;
        return $params;
    }
    
    function save_booking_details(){
        //print_r($this->params); die();
        $bookingDetails = new BoookingDetails($this->map_booking_details_params($this->params));
        $bookingDetails->save();
        $bookingPayment = new BookingPayment($this->map_payment_params($this->params));
        $bookingPayment->save();
        foreach ($this->params['rooms'] as $room) {
            $bookingRooms = new BookingRoons($this->map_booking_rooms_params($room, $bookingDetails->getBooking_detail_id()));    
            $bookingRooms->save();    
            foreach ($room['guests'] as $type => $guests){                               
                $this->save_booking_guest($type,$bookingRooms, $guests);
            }
        }
    }
    
    function save_booking_guest($type, BookingRoons $bookingRoom, $guests){
        foreach ($guests as $guest) {
            $guest = new BookingGuests(array( "booking_detail_id" => $bookingRoom->getBooking_detail_id(),
                                              "booking_room_id" => $bookingRoom->getBooking_room_id(),
                                              "guest_first_name"  => $guest['first_name'],
                                              "guest_tittle" => $guest['title'],
                                              "guest_last_name" => $guest['last_name'],
                                              "guest_age" => ($type == 'child' ? $guest['age'] : 0),
                                              "guest_type" => ($type == 'child' ? 'C' : 'A')));
            $guest->save();
        }
    }

    function map_payment_params($params){

        return array (  'booking_id' => $this->booking_id,
                        'name_credit_card_holder' => $params['cc_holder_name'],
                        'credit_card_type' =>$params['cc_type'] ,
                        'credit_card_number' => $params['cc_number'],
                        'credit_card_expiry_month' => $params['card_expiry_month'],
                        'credit_card_expiry_year' => $params['card_expiry_year'],
                        'credit_card_security_code' => $params['cc_security_code'],
                        'address_1' => $params['cc_address1'],
                        'address_2' => $params['cc_address2'],
                        'town' => $params['cc_city'],
                        'county' => $params['billing_county'],
                        'country' => $params['cc_country_code']);
    }
    
}